//
//  ARCAndMemoryManagementTest.m
//  test_simple_project
//
//  ARC和内存管理语法特性测试实现
//

#import "ARCAndMemoryManagementTest.h"
#import <objc/runtime.h>
#import <mach/mach.h>

// 全局常量定义
NSString * const ARCMemoryManagementNotification = @"ARCMemoryManagementNotification";
NSString * const ARCMemoryWarningNotification = @"ARCMemoryWarningNotification";

@interface ARCAndMemoryManagementTest ()

// 私有属性用于内存管理测试
@property (strong, nonatomic) NSTimer *memoryTestTimer;
@property (strong, nonatomic) NSMutableArray *memoryTestObjects;

@end

@implementation ARCAndMemoryManagementTest

- (instancetype)init {
    self = [super init];
    if (self) {
        // 初始化强引用属性
        _strongString = @"Strong Reference String";
        _strongArray = [[NSMutableArray alloc] init];
        _strongDictionary = [[NSMutableDictionary alloc] init];
        _memoryTestObjects = [[NSMutableArray alloc] init];
        
        // 初始化弱引用集合
        _weakObjectsHashTable = [NSHashTable weakObjectsHashTable];
        _weakKeysMapTable = [NSMapTable weakToStrongObjectsMapTable];
        
        NSLog(@"ARCAndMemoryManagementTest 初始化完成");
    }
    return self;
}

- (void)dealloc {
    ARC_LOG_DEALLOC;
    
    // 清理定时器
    [self.memoryTestTimer invalidate];
    
    // 移除通知观察
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    NSLog(@"ARCAndMemoryManagementTest 已释放");
}

#pragma mark - __autoreleasing 参数方法实现

- (BOOL)performOperationWithError:(NSError * __autoreleasing *)error {
    // 模拟可能失败的操作
    BOOL shouldSucceed = arc4random_uniform(2) == 0;
    
    if (!shouldSucceed && error) {
        *error = [NSError errorWithDomain:@"ARCTestDomain" 
                                     code:1001 
                                 userInfo:@{NSLocalizedDescriptionKey: @"操作失败"}];
        return NO;
    }
    
    return YES;
}

- (BOOL)validateInputWithError:(NSError * __autoreleasing *)error {
    // 模拟输入验证
    if (self.strongString.length == 0) {
        if (error) {
            *error = [NSError errorWithDomain:@"ARCTestDomain" 
                                         code:1002 
                                     userInfo:@{NSLocalizedDescriptionKey: @"输入字符串为空"}];
        }
        return NO;
    }
    
    return YES;
}

#pragma mark - 循环引用测试方法实现

- (void)demonstrateStrongReferenceCycle {
    NSLog(@"演示强引用循环问题");
    
    // 创建父子对象，演示循环引用
    ARCTestParent *parent = [[ARCTestParent alloc] initWithName:@"Parent"];
    ARCTestChild *child = [[ARCTestChild alloc] initWithName:@"Child" parent:parent];
    
    // 如果父类对子类使用强引用，子类对父类也使用强引用，就会形成循环引用
    // 在我们的设计中，子类对父类使用弱引用来避免这个问题
    [parent addChild:child];
    
    NSLog(@"父对象: %@, 子对象: %@", parent.parentName, child.childName);
    NSLog(@"子对象的父引用: %@", child.parent.parentName);
    
    // 当方法结束时，parent和child都会被正确释放，因为没有循环引用
}

- (void)demonstrateWeakReferencePattern {
    NSLog(@"演示弱引用模式");
    
    // 创建委托对象
    ARCTestDelegate *delegate = [[ARCTestDelegate alloc] initWithName:@"TestDelegate" owner:self];
    
    // 设置弱引用委托
    self.weakDelegate = delegate;
    
    if ([self.weakDelegate respondsToSelector:@selector(delegateName)]) {
        NSLog(@"设置弱引用委托: %@", [(ARCTestDelegate *)self.weakDelegate delegateName]);
    }
    
    // 调用委托方法
    if ([self.weakDelegate respondsToSelector:@selector(memoryManagementCallback)]) {
        [self.weakDelegate memoryManagementCallback];
    }
    
    // 当delegate超出作用域时，weakDelegate会自动变为nil
    delegate = nil;
    
    // 延迟检查弱引用是否已置nil
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"委托对象释放后，弱引用是否为nil: %@", self.weakDelegate ? @"NO" : @"YES");
    });
}

- (void)demonstrateParentChildRelationship {
    NSLog(@"演示父子关系内存管理");
    
    ARCTestParent *parent = [[ARCTestParent alloc] initWithName:@"MainParent"];
    
    // 创建多个子对象
    for (int i = 0; i < 3; i++) {
        NSString *childName = [NSString stringWithFormat:@"Child%d", i];
        ARCTestChild *child = [[ARCTestChild alloc] initWithName:childName parent:parent];
        [parent addChild:child];
        
        // 为子对象添加一些玩具
        [child addToy:[NSString stringWithFormat:@"Toy%d", i]];
    }
    
    NSLog(@"父对象有 %lu 个子对象", (unsigned long)parent.children.count);
    
    // 移除一个子对象
    if (parent.children.count > 0) {
        ARCTestChild *firstChild = parent.children.firstObject;
        NSLog(@"移除子对象: %@", firstChild.childName);
        [parent removeChild:firstChild];
    }
    
    NSLog(@"移除后父对象有 %lu 个子对象", (unsigned long)parent.children.count);
    
    // 清理所有子对象
    [parent removeAllChildren];
    NSLog(@"清理后父对象有 %lu 个子对象", (unsigned long)parent.children.count);
}

#pragma mark - Block内存管理实现

- (void)demonstrateBlockMemoryManagement {
    NSLog(@"演示Block内存管理");
    
    // 强引用self的Block（可能导致循环引用）
    void (^strongSelfBlock)(void) = ^{
        NSLog(@"强引用Block访问self: %@", self.strongString);
        // 这里直接使用self会创建强引用
    };
    
    // 弱引用self的Block（推荐模式）
    ARC_WEAK_SELF;
    void (^weakSelfBlock)(void) = ^{
        ARC_STRONG_SELF;
        if (strongSelf) {
            NSLog(@"弱引用Block访问self: %@", strongSelf.strongString);
        } else {
            NSLog(@"self已被释放");
        }
    };
    
    strongSelfBlock();
    weakSelfBlock();
}

- (void)demonstrateBlockWeakSelfPattern {
    NSLog(@"演示Block弱引用self模式");
    
    // 使用宏简化弱引用模式
    ARC_WEAK_SELF;
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 在异步Block中使用弱引用
        ARC_STRONG_SELF;
        if (!strongSelf) {
            NSLog(@"对象已被释放，取消异步操作");
            return;
        }
        
        // 模拟耗时操作
        [NSThread sleepForTimeInterval:1.0];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            // 在嵌套Block中再次检查
            ARC_STRONG_SELF;
            if (strongSelf) {
                NSLog(@"异步操作完成，更新UI: %@", strongSelf.strongString);
            }
        });
    });
}

- (void)demonstrateBlockStrongWeakDance {
    NSLog(@"演示Block强弱引用舞蹈");
    
    ARC_WEAK_SELF;
    
    // 第一层：弱引用
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 第二层：转为强引用
        ARC_STRONG_SELF;
        if (!strongSelf) return;
        
        NSLog(@"第一步：获得强引用");
        
        // 第三层：再次使用弱引用
        dispatch_async(dispatch_get_main_queue(), ^{
            ARC_STRONG_SELF;
            if (!strongSelf) return;
            
            NSLog(@"第二步：主队列中的强引用");
            
            // 第四层：异步操作
            [strongSelf performAsyncOperationWithCompletion:^(BOOL success) {
                NSLog(@"第三步：完成回调");
            }];
        });
    });
}

- (void)performAsyncOperationWithCompletion:(void(^)(BOOL success))completion {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (completion) {
            completion(YES);
        }
    });
}

#pragma mark - 集合类内存管理实现

- (void)demonstrateCollectionMemoryManagement {
    NSLog(@"演示集合类内存管理");
    
    // 强引用集合
    NSMutableArray *strongArray = [[NSMutableArray alloc] init];
    NSMutableDictionary *strongDictionary = [[NSMutableDictionary alloc] init];
    
    // 创建测试对象
    ARCTestChild *testObject = [[ARCTestChild alloc] initWithName:@"TestObject" parent:nil];
    
    // 添加到强引用集合
    [strongArray addObject:testObject];
    strongDictionary[@"testKey"] = testObject;
    
    NSLog(@"对象添加到强引用集合");
    
    // 即使局部变量testObject被置nil，对象仍然被集合持有
    testObject = nil;
    
    NSLog(@"局部变量置nil后，集合中的对象: %@", [strongArray.firstObject childName]);
    
    // 从集合中移除对象，对象才会被释放
    [strongArray removeAllObjects];
    [strongDictionary removeAllObjects];
    
    NSLog(@"从集合中移除对象");
}

- (void)demonstrateWeakCollections {
    NSLog(@"演示弱引用集合");
    
    // 创建弱引用集合
    NSHashTable *weakHashTable = [NSHashTable weakObjectsHashTable];
    NSMapTable *weakMapTable = [NSMapTable weakToStrongObjectsMapTable];
    
    // 创建测试对象
    ARCTestChild *testObject1 = [[ARCTestChild alloc] initWithName:@"WeakObject1" parent:nil];
    ARCTestChild *testObject2 = [[ARCTestChild alloc] initWithName:@"WeakObject2" parent:nil];
    
    // 添加到弱引用集合
    [weakHashTable addObject:testObject1];
    [weakMapTable setObject:@"value1" forKey:testObject1];
    [weakMapTable setObject:@"value2" forKey:testObject2];
    
    NSLog(@"弱引用集合中的对象数量: HashTable=%lu, MapTable=%lu", 
          (unsigned long)weakHashTable.count, (unsigned long)weakMapTable.count);
    
    // 释放对象
    testObject1 = nil;
    testObject2 = nil;
    
    // 弱引用集合会自动清理已释放的对象
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"对象释放后弱引用集合中的对象数量: HashTable=%lu, MapTable=%lu", 
              (unsigned long)weakHashTable.count, (unsigned long)weakMapTable.count);
    });
}

- (void)demonstrateCopySemantics {
    NSLog(@"演示拷贝语义");
    
    // 字符串的拷贝语义
    NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"Original"];
    
    // copy属性会创建不可变副本
    NSString *copiedString = [mutableString copy];
    
    // 修改原始字符串
    [mutableString appendString:@" Modified"];
    
    NSLog(@"原始字符串: %@", mutableString);
    NSLog(@"拷贝的字符串: %@", copiedString);
    
    // 数组的拷贝语义
    NSMutableArray *mutableArray = [@[@"A", @"B", @"C"] mutableCopy];
    NSArray *copiedArray = [mutableArray copy];
    
    [mutableArray addObject:@"D"];
    
    NSLog(@"原始数组: %@", mutableArray);
    NSLog(@"拷贝的数组: %@", copiedArray);
}

#pragma mark - 自动释放池实现

- (void)demonstrateAutoreleasePool {
    NSLog(@"演示自动释放池");

    @autoreleasepool {
        NSMutableString *tempString = [[NSMutableString alloc] init];
        for (int i = 0; i < 1000; i++) {
            [tempString appendFormat:@"Item %d ", i];
        }
        NSLog(@"自动释放池中创建了大量临时对象");
        // 当离开这个作用域时，自动释放池会被清理
    }

    NSLog(@"自动释放池已清理");
}

- (void)demonstrateNestedAutoreleasePools {
    NSLog(@"演示嵌套自动释放池");

    @autoreleasepool {
        NSLog(@"外层自动释放池");

        @autoreleasepool {
            NSLog(@"内层自动释放池");
            NSMutableArray *tempArray = [[NSMutableArray alloc] init];
            for (int i = 0; i < 100; i++) {
                [tempArray addObject:[NSString stringWithFormat:@"Object %d", i]];
            }
            NSLog(@"内层池中创建了 %lu 个对象", (unsigned long)tempArray.count);
        }

        NSLog(@"内层自动释放池已清理");
    }

    NSLog(@"外层自动释放池已清理");
}

- (void)demonstrateAutoreleasePoolInLoop {
    NSLog(@"演示循环中的自动释放池");

    for (int i = 0; i < 10; i++) {
        @autoreleasepool {
            NSString *tempString = [NSString stringWithFormat:@"循环 %d 中的临时字符串", i];
            NSArray *tempArray = @[tempString, @"额外对象1", @"额外对象2"];
            NSLog(@"循环 %d: 创建了 %lu 个临时对象", i, (unsigned long)tempArray.count);
            // 每次循环结束时自动释放池都会清理
        }
    }

    NSLog(@"所有循环的自动释放池都已清理");
}

#pragma mark - 内存管理最佳实践实现

- (void)demonstratePropertyMemorySemantics {
    NSLog(@"演示属性内存语义");

    // 强引用属性
    self.strongString = @"新的强引用字符串";
    NSLog(@"强引用属性: %@", self.strongString);

    // 弱引用属性
    ARCTestDelegate *tempDelegate = [[ARCTestDelegate alloc] initWithName:@"临时委托" owner:self];
    self.weakDelegate = tempDelegate;
    NSLog(@"弱引用属性设置完成");

    // 当tempDelegate超出作用域时，weakDelegate会自动置nil
    tempDelegate = nil;

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"临时委托释放后，弱引用是否为nil: %@", self.weakDelegate ? @"NO" : @"YES");
    });
}

- (void)demonstrateMethodParameterMemorySemantics {
    NSLog(@"演示方法参数内存语义");

    NSError *error = nil;
    BOOL success = [self performOperationWithError:&error];

    if (success) {
        NSLog(@"操作成功");
    } else {
        NSLog(@"操作失败: %@", error.localizedDescription);
    }
}

- (void)demonstrateReturnValueMemorySemantics {
    NSLog(@"演示返回值内存语义");

    // 返回强引用对象
    NSString *returnedString = [self createStrongString];
    NSLog(@"返回的强引用字符串: %@", returnedString);

    // 返回弱引用对象
    id weakObject = [self createWeakReference];
    NSLog(@"返回的弱引用对象: %@", weakObject ? @"存在" : @"nil");
}

- (NSString *)createStrongString {
    return [[NSString alloc] initWithFormat:@"强引用字符串 - %@", [NSDate date]];
}

- (id)createWeakReference {
    ARCTestChild *tempChild = [[ARCTestChild alloc] initWithName:@"临时子对象" parent:nil];
    __weak id weakRef = tempChild;
    tempChild = nil; // 立即释放
    return weakRef; // 返回弱引用，可能已经是nil
}

#pragma mark - 内存泄漏检测实现

- (void)demonstrateMemoryLeakDetection {
    NSLog(@"演示内存泄漏检测");

    // 创建可能导致内存泄漏的对象
    ARCTestParent *parent = [[ARCTestParent alloc] initWithName:@"泄漏测试父对象"];

    // 正确的做法：使用弱引用避免循环引用
    ARCTestChild *child = [[ARCTestChild alloc] initWithName:@"泄漏测试子对象" parent:parent];
    [parent addChild:child];

    NSLog(@"创建了父子对象，使用弱引用避免循环引用");

    // 清理引用
    [parent removeAllChildren];
    parent = nil;
    child = nil;

    NSLog(@"对象已清理，无内存泄漏");
}

- (void)demonstrateMemoryDebugging {
    NSLog(@"演示内存调试");

    // 记录当前内存使用
    [self logMemoryUsage];

    // 创建大量对象
    NSMutableArray *largeArray = [[NSMutableArray alloc] init];
    for (int i = 0; i < 10000; i++) {
        [largeArray addObject:[NSString stringWithFormat:@"对象 %d", i]];
    }

    NSLog(@"创建了 %lu 个对象", (unsigned long)largeArray.count);
    [self logMemoryUsage];

    // 清理对象
    [largeArray removeAllObjects];
    largeArray = nil;

    NSLog(@"对象已清理");
    [self logMemoryUsage];
}

- (void)logMemoryUsage {
    struct mach_task_basic_info info;
    mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT;
    kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);

    if (kerr == KERN_SUCCESS) {
        NSLog(@"内存使用: %.2f MB", info.resident_size / (1024.0 * 1024.0));
    } else {
        NSLog(@"无法获取内存使用信息");
    }
}

@end

#pragma mark - ARCTestParent实现

@implementation ARCTestParent

- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _parentName = [name copy];
        _children = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)dealloc {
    ARC_LOG_DEALLOC;
    NSLog(@"ARCTestParent '%@' 已释放", self.parentName);
}

- (void)addChild:(ARCTestChild *)child {
    if (child && ![self.children containsObject:child]) {
        [self.children addObject:child];
        child.parent = self; // 子对象持有父对象的弱引用
        NSLog(@"父对象 '%@' 添加了子对象 '%@'", self.parentName, child.childName);
    }
}

- (void)removeChild:(ARCTestChild *)child {
    if ([self.children containsObject:child]) {
        child.parent = nil;
        [self.children removeObject:child];
        NSLog(@"父对象 '%@' 移除了子对象 '%@'", self.parentName, child.childName);
    }
}

- (void)removeAllChildren {
    for (ARCTestChild *child in self.children) {
        child.parent = nil;
    }
    [self.children removeAllObjects];
    NSLog(@"父对象 '%@' 移除了所有子对象", self.parentName);
}

@end

#pragma mark - ARCTestChild实现

@implementation ARCTestChild

- (instancetype)initWithName:(NSString *)name parent:(ARCTestParent *)parent {
    self = [super init];
    if (self) {
        _childName = [name copy];
        _parent = parent; // 弱引用父对象
        _toys = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)dealloc {
    ARC_LOG_DEALLOC;
    NSLog(@"ARCTestChild '%@' 已释放", self.childName);
}

- (void)addToy:(NSString *)toy {
    if (toy) {
        [self.toys addObject:toy];
        NSLog(@"子对象 '%@' 添加了玩具 '%@'", self.childName, toy);
    }
}

- (void)playWithToys {
    NSLog(@"子对象 '%@' 正在玩 %lu 个玩具", self.childName, (unsigned long)self.toys.count);
    for (NSString *toy in self.toys) {
        NSLog(@"  - 玩具: %@", toy);
    }
}

@end

#pragma mark - ARCTestDelegate实现

@implementation ARCTestDelegate

- (instancetype)initWithName:(NSString *)name owner:(ARCAndMemoryManagementTest *)owner {
    self = [super init];
    if (self) {
        _delegateName = [name copy];
        _owner = owner; // 弱引用拥有者
    }
    return self;
}

- (void)dealloc {
    ARC_LOG_DEALLOC;
    NSLog(@"ARCTestDelegate '%@' 已释放", self.delegateName);
}

- (void)memoryManagementCallback {
    NSLog(@"委托 '%@' 执行内存管理回调", self.delegateName);
}

- (void)weakReferenceCallback:(id)sender {
    NSLog(@"委托 '%@' 执行弱引用回调，发送者: %@", self.delegateName, sender);
}

@end

#pragma mark - ARCTestObserver实现

@implementation ARCTestObserver

- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _observerName = [name copy];
    }
    return self;
}

- (void)dealloc {
    ARC_LOG_DEALLOC;
    [self stopObserving];
    NSLog(@"ARCTestObserver '%@' 已释放", self.observerName);
}

- (void)startObserving:(id)object {
    self.observedObject = object;
    NSLog(@"观察者 '%@' 开始观察对象", self.observerName);
}

- (void)stopObserving {
    self.observedObject = nil;
    NSLog(@"观察者 '%@' 停止观察", self.observerName);
}

@end

#pragma mark - ARCMemoryUtils实现

@implementation ARCMemoryUtils

+ (NSHashTable *)createWeakObjectsHashTable {
    return [NSHashTable weakObjectsHashTable];
}

+ (NSMapTable *)createWeakKeysStrongValuesMapTable {
    return [NSMapTable weakToStrongObjectsMapTable];
}

+ (NSMapTable *)createStrongKeysWeakValuesMapTable {
    return [NSMapTable strongToWeakObjectsMapTable];
}

+ (NSUInteger)getCurrentMemoryUsage {
    struct mach_task_basic_info info;
    mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT;
    kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);

    if (kerr == KERN_SUCCESS) {
        return info.resident_size;
    }
    return 0;
}

+ (void)logMemoryStatistics {
    NSUInteger memoryUsage = [self getCurrentMemoryUsage];
    NSLog(@"当前内存使用: %.2f MB", memoryUsage / (1024.0 * 1024.0));
}

+ (void)forceGarbageCollection {
    // 在ARC环境下，没有显式的垃圾回收
    // 但可以通过创建自动释放池来强制清理
    @autoreleasepool {
        // 空的自动释放池，用于清理自动释放对象
    }
}

+ (BOOL)detectRetainCycleInObject:(id)object {
    // 这是一个简化的循环引用检测示例
    // 实际的检测需要更复杂的算法
    NSLog(@"检测对象 %@ 的循环引用（简化版本）", object);
    return NO; // 简化实现，总是返回NO
}

+ (NSArray *)findRetainCyclePathFromObject:(id)object {
    // 简化实现，返回空数组
    NSLog(@"查找从对象 %@ 开始的循环引用路径", object);
    return @[];
}

@end
